﻿using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Accord.Math.Wavelets;
using System;
using System.Text;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;

namespace MyWatermark
{

    //public class HaarWaveletWatermark
    //{
    //    // 配置参数
    //    private const int BlockSize = 512;       // 基础分块尺寸
    //    private const int DwtLevel = 2;           // 分解级数
    //    private const double Alpha = 0.1;         // 嵌入强度
    //    private const int PayloadBits = 256;      // 水印容量（32字符）

    //    // 嵌入水印
    //    public static void Embed(string inputPath, string outputPath, string watermark)
    //    {
    //        using var image = Image.Load<Rgb24>(inputPath);
    //        var yMatrix = GetYChannel(image);

    //        // 执行DWT分解
    //        var coeffs = PerformHaarDWT(yMatrix, DwtLevel);

    //        // 生成水印位
    //        var bits = StringToBits(watermark, PayloadBits);

    //        // 在二级分解的HL子带嵌入
    //        EmbedInSubband(coeffs.Level2.HL, bits, startIndex: 128);

    //        // 逆变换重构
    //        var reconstructed = PerformHaarIDWT(coeffs, DwtLevel);

    //        // 更新并保存
    //        ApplyYChannel(image, reconstructed);
    //        image.Save(outputPath);
    //    }

    //    private static bool[] StringToBits(string watermark, int payloadBits)
    //    {
    //        throw new NotImplementedException();
    //    }

    //    // 提取水印
    //    public static string Extract(string watermarkedPath)
    //    {
    //        using var image = Image.Load<Rgb24>(watermarkedPath);
    //        var yMatrix = GetYChannel(image);

    //        var coeffs = PerformHaarDWT(yMatrix, DwtLevel);
    //        var bits = ExtractFromSubband(coeffs.Level2.HL, PayloadBits, startIndex: 128);
    //        return BitsToString(bits);
    //    }

    //    private static string BitsToString(bool[] bits)
    //    {
    //        throw new NotImplementedException();
    //    }

    //    #region 小波变换实现
    //    private static DwtCoefficients PerformHaarDWT(double[,] data, int levels)
    //    {
    //        int size = data.GetLength(0);
    //        var haar = new Haar(levels);
    //        var coeffs = new DwtCoefficients();

    //        // 一级分解
    //        var level1 = Haar2D(data, haar);
    //        coeffs.Level1 = level1;

    //        // 二级分解（处理LL子带）
    //        if (levels >= 2)
    //        {
    //            var level2 = Haar2D(level1.LL, haar);
    //            coeffs.Level2 = level2;
    //        }

    //        return coeffs;
    //    }

    //    private static double[,] PerformHaarIDWT(DwtCoefficients coeffs, int levels)
    //    {
    //        // 二级逆变换
    //        if (levels >= 2)
    //        {
    //            var reconstructedLL = InverseHaar2D(coeffs.Level2);
    //            coeffs.Level1.LL = reconstructedLL;
    //        }

    //        // 一级逆变换
    //        return InverseHaar2D(coeffs.Level1);
    //    }

    //    private static Subbands Haar2D(double[,] data, Haar haar)
    //    {
    //        int size = data.GetLength(0);
    //        double[] row = new double[size];
    //        double[] col = new double[size];

    //        // 行变换
    //        for (int y = 0; y < size; y++)
    //        {
    //            Buffer.BlockCopy(data, y * size * sizeof(double), row, 0, size * sizeof(double));
    //            haar.Forward(row);
    //            Buffer.BlockCopy(row, 0, data, y * size * sizeof(double), size * sizeof(double));
    //        }

    //        // 列变换
    //        for (int x = 0; x < size; x++)
    //        {
    //            for (int y = 0; y < size; y++) col[y] = data[y, x];
    //            haar.Forward(col);
    //            for (int y = 0; y < size; y++) data[y, x] = col[y];
    //        }

    //        // 分割子带
    //        return SplitSubbands(data);
    //    }

    //    private static double[,] InverseHaar2D(Subbands subbands)
    //    {
    //        int size = subbands.LL.GetLength(0) * 2;
    //        var merged = MergeSubbands(subbands);

    //        double[] row = new double[size];
    //        double[] col = new double[size];
    //        var haar = new Haar(1);

    //        // 列逆变换
    //        for (int x = 0; x < size; x++)
    //        {
    //            for (int y = 0; y < size; y++) col[y] = merged[y, x];
    //            haar.Backward(col);
    //            for (int y = 0; y < size; y++) merged[y, x] = col[y];
    //        }

    //        // 行逆变换
    //        for (int y = 0; y < size; y++)
    //        {
    //            Buffer.BlockCopy(merged, y * size * sizeof(double), row, 0, size * sizeof(double));
    //            haar.Backward(row);
    //            Buffer.BlockCopy(row, 0, merged, y * size * sizeof(double), size * sizeof(double));
    //        }

    //        return merged;
    //    }
    //    #endregion

    //    #region 水印操作
    //    private static void EmbedInSubband(double[,] subband, bool[] bits, int startIndex)
    //    {
    //        int index = startIndex;
    //        foreach (bool bit in bits)
    //        {
    //            if (index >= subband.Length) break;

    //            int y = index / subband.GetLength(1);
    //            int x = index % subband.GetLength(1);

    //            double q = Math.Floor(subband[y, x] / Alpha);
    //            subband[y, x] = (q + (bit ? 0.75 : 0.25)) * Alpha;
    //            index++;
    //        }
    //    }

    //    private static bool[] ExtractFromSubband(double[,] subband, int payloadBits, int startIndex)
    //    {
    //        var bits = new bool[payloadBits];
    //        int index = startIndex;

    //        for (int i = 0; i < payloadBits; i++)
    //        {
    //            if (index >= subband.Length) break;

    //            int y = index / subband.GetLength(1);
    //            int x = index % subband.GetLength(1);

    //            double q = subband[y, x] / Alpha;
    //            bits[i] = (q % 1.0) > 0.5;
    //            index++;
    //        }
    //        return bits;
    //    }
    //    #endregion

    //    #region 核心算法
    //    // 图像预处理（自动适配尺寸）
    //    private static Image<Rgb24> PreprocessImage(Image<Rgb24> image)
    //    {
    //        // 计算最小满足条件的尺寸
    //        int newSize = (int)Math.Pow(2, (int)Math.Log(Math.Max(image.Width, image.Height), 2) + 1);

    //        // 创建新画布
    //        var canvas = new Image<Rgb24>(newSize, newSize);
    //        canvas.Mutate(x => x.BackgroundColor(Color.Black));

    //        // 居中粘贴原图
    //        canvas.Mutate(x => x.DrawImage(image, new Point(
    //            (newSize - image.Width) / 2,
    //            (newSize - image.Height) / 2),
    //            1f));

    //        // 记录原始尺寸到元数据
    //        canvas.Metadata.ExifProfile = new ExifProfile();
    //        canvas.Metadata.ExifProfile.SetValue(ExifTag.Software, $"ORIG_SIZE:{image.Width}x{image.Height}");

    //        return canvas;
    //    }

    //    // 分块嵌入算法
    //    private static void EmbedAcrossBlocks(List<Image<Rgb24>> blocks, bool[] bits)
    //    {
    //        int bitsPerBlock = bits.Length / blocks.Count;
    //        var haar = new Haar(2);

    //        Parallel.For(0, blocks.Count, i =>
    //        {
    //            var block = blocks[i];
    //            var yChannel = GetYChannel(block);

    //            // 执行DWT
    //            var coeffs = PerformHaarDWT(yChannel, haar);

    //            // 分配水印位
    //            int start = i * bitsPerBlock;
    //            int end = (i == blocks.Count - 1) ? bits.Length : start + bitsPerBlock;
    //            var subBits = bits[start..end];

    //            // 在HL子带嵌入
    //            EmbedInSubband(coeffs.HL, subBits);

    //            // 逆变换更新
    //            var reconstructed = PerformHaarIDWT(coeffs, haar);
    //            ApplyYChannel(block, reconstructed);
    //        });
    //    }
    //    #endregion

    //    #region 分块处理方法
    //    private static List<Image<Rgb24>> SplitIntoBlocks(Image<Rgb24> image)
    //    {
    //        var blocks = new List<Image<Rgb24>>();
    //        int xBlocks = image.Width / BlockSize;
    //        int yBlocks = image.Height / BlockSize;

    //        for (int y = 0; y < yBlocks; y++)
    //        {
    //            for (int x = 0; x < xBlocks; x++)
    //            {
    //                var rect = new Rectangle(
    //                    x * BlockSize,
    //                    y * BlockSize,
    //                    BlockSize,
    //                    BlockSize);

    //                var block = image.Clone(ctx => ctx.Crop(rect));
    //                blocks.Add(block);
    //            }
    //        }
    //        return blocks;
    //    }

    //    private static Image<Rgb24> MergeBlocks(List<Image<Rgb24>> blocks, Size originalSize)
    //    {
    //        int cols = (int)Math.Ceiling((double)originalSize.Width / BlockSize);
    //        int rows = (int)Math.Ceiling((double)originalSize.Height / BlockSize);

    //        var canvas = new Image<Rgb24>(cols * BlockSize, rows * BlockSize);

    //        for (int i = 0; i < blocks.Count; i++)
    //        {
    //            int x = (i % cols) * BlockSize;
    //            int y = (i / cols) * BlockSize;
    //            canvas.Mutate(ctx => ctx.DrawImage(blocks[i], new Point(x, y), 1f));
    //        }

    //        // 裁剪回原始尺寸
    //        canvas.Mutate(ctx => ctx.Crop(originalSize));
    //        return canvas;
    //    }
    //    #endregion


    //    #region 辅助工具
    //    // 获取Y通道（灰度转换）
    //    private static double[,] GetYChannel(Image<Rgb24> image)
    //    {
    //        int size = image.Size.Width;
    //        var matrix = new double[size, size];
    //        image.ProcessPixelRows(accessor =>
    //        {
    //            for (int y = 0; y < accessor.Height; y++)
    //            {
    //                var row = accessor.GetRowSpan(y);
    //                for (int x = 0; x < row.Length; x++)
    //                {
    //                    var pixel = row[x];
    //                    matrix[y, x] = 0.299 * pixel.R + 0.587 * pixel.G + 0.114 * pixel.B;
    //                }
    //            }
    //        });
    //        return matrix;
    //    }

    //    // 应用Y通道
    //    private static void ApplyYChannel(Image<Rgb24> image, double[,] yMatrix)
    //    {
    //        image.ProcessPixelRows(accessor =>
    //        {
    //            for (int y = 0; y < accessor.Height; y++)
    //            {
    //                var row = accessor.GetRowSpan(y);
    //                for (int x = 0; x < row.Length; x++)
    //                {
    //                    byte yVal = (byte)Math.Clamp(yMatrix[y, x], 0, 255);
    //                    row[x] = new Rgb24(yVal, yVal, yVal);
    //                }
    //            }
    //        });
    //    }

    //    // 子带分割与合并
    //    private static Subbands SplitSubbands(double[,] data)
    //    {
    //        int half = data.GetLength(0) / 2;
    //        return new Subbands
    //        {
    //            LL = Slice(data, 0, half, 0, half),
    //            HL = Slice(data, 0, half, half, 2 * half),
    //            LH = Slice(data, half, 2 * half, 0, half),
    //            HH = Slice(data, half, 2 * half, half, 2 * half)
    //        };
    //    }

    //    private static double[,] MergeSubbands(Subbands subbands)
    //    {
    //        int size = subbands.LL.GetLength(0) * 2;
    //        var merged = new double[size, size];
    //        CopySubband(subbands.LL, merged, 0, 0);
    //        CopySubband(subbands.HL, merged, 0, size / 2);
    //        CopySubband(subbands.LH, merged, size / 2, 0);
    //        CopySubband(subbands.HH, merged, size / 2, size / 2);
    //        return merged;
    //    }
    //    #endregion

    //    #region 数据结构
    //    private class DwtCoefficients
    //    {
    //        public Subbands Level1 { get; set; }
    //        public Subbands Level2 { get; set; }
    //    }

    //    private class Subbands
    //    {
    //        public double[,] LL { get; set; } // 近似分量
    //        public double[,] HL { get; set; } // 水平细节
    //        public double[,] LH { get; set; } // 垂直细节
    //        public double[,] HH { get; set; } // 对角线细节
    //    }
    //    #endregion

    //    // 其他工具方法（Slice, CopySubband等）...
    //}

    public class test2()
    {
        public static void test22()
        {
            //string imageLocation = @"D:\ywd\work\ncs\新水印的尝试\blind_watermark\blind_watermark\examples\pic\original.jpg";
            //string outLocation = @"D:\ywd\work\ncs\新水印的尝试\blind_watermark\blind_watermark\examples\pic\out2222222.jpg";

            //// 嵌入水印
            //HaarWaveletWatermark.Embed(imageLocation, outLocation, "Copyright@2024");

            //// 提取水印
            //string watermark = HaarWaveletWatermark.Extract(outLocation);
            //Console.WriteLine($"提取结果：{watermark}");
        }
    }

}
